
package org.sidora.core;

import java.text.NumberFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import java.util.logging.Level;

import org.sidora.core.util.AbstractFactory;
import org.sidora.core.util.AbstractInventory;
import org.sidora.core.util.LoggerProvider;
import org.sidora.core.util.OCProvider;
import org.sidora.core.util.ParameterCollector;

/**
 * Classe que representa una actuacio arqueologica
 * @author Enric Tartera, Anna Arnalot, Juan Manuel Gimeno, Roger Masgoret
 * @version 1.0
 */

public class Action implements Comparable{
    
    private String id;
    private String name;
    private Site site;
    private Date startDate;
    private Date endDate;
    private String objectives;
    
    //private Set <Assignment> assignments = new TreeSet <Assignment>();
    
    
    private Action(){}
    
    
    public Set<Assignment> getAssignments() {
        return new TreeSet<Assignment>(Assignment.Inventory.getList(this));
    }
    
    
    @Override
    public boolean equals(Object obj) {
        if (obj == this)	return true;
        if (!(obj instanceof Action)) return false;
        Action action = null;
        try {
            action = (Action) obj;
        } catch (Exception e) {
            return false;
        }
        if (this.getId() != action.getId()) return false;
        return true;
    }
    
    @Override
    public String toString() {
        return getName();
    }
    
    
    
    
//    private static class Factory extends AbstractFactory{
//
//        protected Object create(ParameterCollector param) {
//            // La pol�tica de creaci� de jaciments determina que nom�s un usuari
//            // amb rol "admin" pot crear noves intervencions.
//
//
//            return new Action();
//
//
//        }
//    }
    public static class Inventory extends AbstractInventory{
        
        
        
        public boolean exist(final String id) throws Exception{
            
            ObjectContainer db = OCProvider.getInstance();
            ObjectSet<Action> actions = db.query(new Predicate<Action>() {
                
                
                public boolean match(Action candidate) {
                    return candidate.getId().equals(id);
                }
            });
            
            if (actions.hasNext()){
                return true;
            } else {
                return false;
            }
        }
        
        public Action getNewObject(ParameterCollector param) throws Exception{
            //Verifica si existeix en la base d'objectes
            
            String newId= (String) param.get("id");
            
            if (!exist(newId)){
                return new Action();
            }else {
                
                return (Action) getObject(param);
            }
            
        }
        
        
        
        
        public Object getObject(ParameterCollector param) {
            //Carrega la Actuaci� amb el corresponent id
            
            
            final String key = (String) param.get("id");
            ObjectContainer db = OCProvider.getInstance();
            ObjectSet <Action> actions = db.query(new Predicate <Action>() {
                public boolean match(Action anaction) {
                    return (anaction.getId().equals(key));
                }
            });
            
            
            if (actions.hasNext()){
                return actions.next();
            } else throw new RuntimeException("Actuaci� inexistent");
        }
        
        public static List getList() {
            
            ObjectContainer db = OCProvider.getInstance();
            List<Action> list = db.query(Action.class);
            
            return list;
            
        }
        
        @Override
        public KeyObject getNewKey(ParameterCollector param) {
            // TODO Auto-generated method stub
            return null;
        }
        
        public static String getNewKey() {
            ObjectContainer db = OCProvider.getInstance();
            ObjectSet <Action> actions = db.query(Action.class);
            SortedSet <Integer>sorted = new TreeSet<Integer>();
            
            NumberFormat form = NumberFormat.getInstance();
            form.setMinimumIntegerDigits(3);
            
            if (actions.size()!=0){
                while (actions.hasNext()){
                    Action aAction = actions.next();
                    try{
                        Integer integer = Integer.parseInt(aAction.getId());
                        sorted.add(integer);
                    }catch (NumberFormatException e){
                        LoggerProvider.getInstance().log(Level.WARNING,"Not an integer",e);
                    }
                }
                int last = sorted.last().intValue();
                return form.format(last+1);
            } else return "001";
        }
        
        public static List getList(final Site site) {
            ObjectContainer db = OCProvider.getInstance();
            List<Action> list = db.query(new Predicate<Action>(){
                
                @Override
                public boolean match(Action action) {
                    
                    return action.getSite()==site;
                }});
                
                return list;
        }
    }
    
    public int compareTo(Object obj) {
        Action action = (Action) obj;
        return this.toString().compareTo(action.toString());
    }
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public Site getSite() {
        return site;
    }
    
    public void setSite(Site site) {
        this.site = site;
    }
    
    public Date getStartDate() {
        return startDate;
    }
    
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    
    public Date getEndDate() {
        return endDate;
    }
    
    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }
    
    public String getObjectives() {
        return objectives;
    }
    
    public void setObjectives(String objectives) {
        this.objectives = objectives;
    }
    
} // end Actuacio



